package pl.streamsoft.currencyApp.model;

import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

@Entity
@Table(name = "CURRENCY_INFO")
@NamedQueries({ @NamedQuery(name = "CurrencyInfo.getInstanceIfExists", query = "from CurrencyInfo where name = :name and code = :code and converter = :converted"
// , hints = { @QueryHint(name = "org.hibernate.cacheable", value = "true") }
) })
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class CurrencyInfo {

	@Id
	@GeneratedValue
	@Column(name = "CURRENCY_INFO_ID")
	private long currencyInfoId;

	@Column(name = "CURRENCY_NAME", nullable = true)
	private String name;

	@Column(name = "CURRENCY_CONVERTED", nullable = false)
	private int converter;

	@Column(name = "CURRENCY_CODE", nullable = false)
	private String code;

	public CurrencyInfo() {
	}

	private CurrencyInfo(String name, String code, int converted) {
		this.name = name;
		this.code = code;
		this.converter = converted;
	}

	public static CurrencyInfo getInstance(String name, String code,
			int converted) {

		Session session = null;

		try {

			session = DataBaseConector.getInstanceOfSession();
			session.beginTransaction();

			Query query = session
					.getNamedQuery("CurrencyInfo.getInstanceIfExists");

			query.setMaxResults(1);
			query.setString("name", name);
			query.setString("code", code);
			query.setInteger("converted", converted);
			query.setCacheable(true);
			// query.setCacheMode(CacheMode.NORMAL);
			// query.setCacheRegion("INFO_REGION");

			CurrencyInfo currencyInfo = (CurrencyInfo) query.uniqueResult();

			if (currencyInfo == null) {
				currencyInfo = new CurrencyInfo(name, code, converted);
				session.save(currencyInfo);
			}

			return currencyInfo;

		} catch (Exception e) {
			e.printStackTrace();
			return null;

		} finally {
			session.getTransaction().commit();
			session.close();
		}
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getConverter() {
		return converter;
	}

	public void setConverter(int converter) {
		this.converter = converter;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	@Override
	public int hashCode() {
		return name.hashCode();
	}

	@Override
	public boolean equals(Object object) {
		if (!(object instanceof CurrencyInfo)) {
			return false;
		}

		CurrencyInfo info = (CurrencyInfo) object;
		return info.name.equals(name) && info.code.equals(code)
				&& (info.converter == converter);
	}
}
